﻿using System;
using System.Collections.ObjectModel;
using System.Net;
using System.Windows.Threading;
using TweetSharp;
using PocketBlueBird.Configuration;
using System.Windows;

namespace PocketBlueBird.ViewModels
{
    public class MainPanoramaPageViewModels : BaseViewModel
    {
        private TwitterService _service;

        public ObservableCollection<TwitterStatus> Tweets { get; private set; }

        public ObservableCollection<TwitterStatus> MyTweets { get; private set; }

        public ObservableCollection<TwitterStatus> Mentions { get; private set; }

        public ObservableCollection<TwitterDirectMessage> Messages { get; private set; }

        public ObservableCollection<TwitterUser> Followers { get; private set; }

        public ObservableCollection<TwitterUser> Friends { get; private set; }

        public MainPanoramaPageViewModels()
        {
            if (IsAuthorized)
            {
                _service = new TwitterService(
                    _consumerKey,
                    _consumerSecret,
                    App.AccessToken.Token,
                    App.AccessToken.TokenSecret);

                Tweets = new ObservableCollection<TwitterStatus>();
                MyTweets = new ObservableCollection<TwitterStatus>();
                Mentions = new ObservableCollection<TwitterStatus>();
                Messages = new ObservableCollection<TwitterDirectMessage>();
                Followers = new ObservableCollection<TwitterUser>();
                Friends = new ObservableCollection<TwitterUser>();
            }
        }

        internal void GetTweets(Dispatcher dispatcher)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.ListTweetsOnPublicTimeline((statuses, response) =>
            {
                responseHanler(dispatcher, response, () =>
                {
                    foreach (var item in statuses)
                    {
                        if (!App.TweetsDic.ContainsKey(item.Id))
                        {
                            this.Tweets.Add(item);
                            App.TweetsDic.Add(item.Id, item);
                        }
                    }
                });
            }
            );
        }

        private void responseHanler(Dispatcher dispatcher, TwitterResponse response, Action action)
        {
            if (response.StatusCode == HttpStatusCode.OK)
            {
                try
                {
                    dispatcher.BeginInvoke(() =>
                    {
                        action();

                        if (IsGettingData != null)
                        {
                            IsGettingData(false);
                        }
                    });
                }
                catch (Exception ex)
                {
                    ExceptionHandler.ShowExceptionMessage(ex);
                }
            }
            else
            {
                ExceptionHandler.ShowExceptionMessage(response.InnerException);
            }
        }

        internal void GetMyTweets(Dispatcher dispatcher)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.ListTweetsOnUserTimeline((statuses, response) =>
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    try
                    {
                        dispatcher.BeginInvoke(() =>
                        {
                            foreach (var item in statuses)
                            {
                                if (!App.MyTweetsDic.ContainsKey(item.Id))
                                {
                                    this.MyTweets.Add(item);
                                    App.MyTweetsDic.Add(item.Id, item);
                                }
                            }

                            if (IsGettingData != null)
                            {
                                IsGettingData(false);
                            }
                        });
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                else
                {
                    throw new Exception(response.StatusCode.ToString());
                }
            }
            );
        }

        internal void GetMentions(Dispatcher dispatcher)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.ListTweetsMentioningMe((statuses, response) =>
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    try
                    {
                        dispatcher.BeginInvoke(() =>
                        {
                            foreach (var item in statuses)
                            {
                                if (!App.MentionsDic.ContainsKey(item.Id))
                                {
                                    this.Mentions.Add(item);
                                    App.MentionsDic.Add(item.Id, item);
                                }
                            }

                            if (IsGettingData != null)
                            {
                                IsGettingData(false);
                            }
                        });
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }
                else
                {
                    throw new Exception(response.StatusCode.ToString());
                }
            }
            );
        }

        internal void GetMessages(Dispatcher dispatcher)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.ListDirectMessagesReceived((messages, response) =>
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    try
                    {
                        dispatcher.BeginInvoke(() =>
                        {
                            foreach (var msg in messages)
                            {
                                if (!App.MessagesDic.ContainsKey(msg.Id))
                                {
                                    this.Messages.Add(msg);
                                    App.MessagesDic.Add(msg.Id, msg);
                                }
                            }

                            if (IsGettingData != null)
                            {
                                IsGettingData(false);
                            }
                        });
                    }
                    catch (Exception ex)
                    {

                        throw;
                    }
                }
                else
                {
                    throw new Exception(response.StatusCode.ToString());
                }
            }
            );
        }

        internal void GetFollowers(Dispatcher dispatcher)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.ListFollowers((followers, response) =>
           {
               if (response.StatusCode == HttpStatusCode.OK)
               {
                   try
                   {
                       dispatcher.BeginInvoke(() =>
                       {
                           foreach (var item in followers)
                           {
                               if (!App.FollowersDic.ContainsKey(item.Id))
                               {
                                   this.Followers.Add(item);
                                   App.FollowersDic.Add(item.Id, item);
                               }
                           }

                           if (IsGettingData != null)
                           {
                               IsGettingData(false);
                           }
                       });
                   }
                   catch (Exception)
                   {

                       throw;
                   }
               }
               else
               {
                   throw new Exception(response.StatusCode.ToString());
               }
           }
           );
        }

        internal void GetFollowing(Dispatcher dispatcher)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.ListFriends((friends, response) =>
            {
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    try
                    {
                        dispatcher.BeginInvoke(() =>
                        {
                            foreach (var item in friends)
                            {
                                if (!App.FriendsDic.ContainsKey(item.Id))
                                {
                                    this.Friends.Add(item);
                                    App.FriendsDic.Add(item.Id, item);
                                }
                            }

                            if (IsGettingData != null)
                            {
                                IsGettingData(false);
                            }
                        });
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }
                else
                {
                    throw new Exception(response.StatusCode.ToString());
                }
            }
           );
        }

        internal void Retweet(Dispatcher dispatcher, long id)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.Retweet(id, (status, response) =>
            {
                responseHanler(dispatcher, response, () =>
                {
                    new Controls.FadingMessage().ShowTextMessage("Retweet Successfully!");
                });
            });
        }

        internal void FavoriteTweet(Dispatcher dispatcher, long id)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.FavoriteTweet(id, (status, response) =>
            {
                responseHanler(dispatcher, response, () =>
                {
                    new Controls.FadingMessage().ShowTextMessage("Favorite Tweet Successfully!");
                });
            });
        }

        internal void SendDirectMessage(Dispatcher dispatcher, int userId)
        {
            if (IsGettingData != null)
            {
                IsGettingData(true);
            }

            _service.SendDirectMessage(userId, "", (msg, response) =>
            {
                responseHanler(dispatcher, response, () =>
                {
                    new Controls.FadingMessage().ShowTextMessage("Send Direct Message Successfully!");
                });
            });
        }
    }
}
